package com.yanqu.road.server.manager.orewar;

import com.yanqu.road.entity.activity.ActivityInfo;
import com.yanqu.road.entity.crossorewar.CrossUserOrePit;
import com.yanqu.road.entity.player.UserBaseInfo;
import com.yanqu.road.entity.player.UserPatrons;
import com.yanqu.road.entity.union.activitygroup.UnionActivityGroup;
import com.yanqu.road.logic.helper.UnionActivityGroupHelper;
import com.yanqu.road.pb.orewar.OreWarProto;
import com.yanqu.road.server.CrossBaseServer;
import com.yanqu.road.server.TempCrossMgr;
import com.yanqu.road.server.manager.union.activitygroup.Cross2UnionActivityGroupMgr;
import com.yanqu.road.server.protocol.GameErrorCode;
import com.yanqu.road.utils.executor.GeneralTask;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;


//盐场争霸活动
public class CrossOreWarMgr extends TempCrossMgr {

    private static Logger logger = LogManager.getLogger(CrossOreWarMgr.class.getName());

    private static Map<Integer, Map<Integer, CrossOreWar>> crossOreWarMap = new ConcurrentHashMap<>();//<活动<分组,盐场>>
    private static Map<Integer, Map<Integer, Object>> activityLock;      //<活动<分组，锁>>

    public static void sendAllUserPit(int activityId, long serverId) {
        for (Map<Integer, CrossOreWar> groupMap : crossOreWarMap.values()) {
            for (CrossOreWar crossOreWar : groupMap.values()) {
                synchronized (getActivityLock(activityId, crossOreWar.getGroupId())) {
                    crossOreWar.sendAllUserPit(serverId);
                }
            }
        }
    }

    public static void syncUserPit(int activityId, long serverId, int pitId) {
        for (Map<Integer, CrossOreWar> groupMap : crossOreWarMap.values()) {
            for (CrossOreWar crossOreWar : groupMap.values()) {
                synchronized (getActivityLock(activityId, crossOreWar.getGroupId())) {
                    crossOreWar.syncCrossOrePit(pitId);
                }
            }
        }
    }

    public static void syncStation(int activityId, long serverId, int stationId, int groupId) {
        synchronized (getActivityLock(activityId,groupId)) {
            CrossOreWar crossOreWar = getCrossOreWar(activityId, groupId);
            if (null != crossOreWar) {
                if (stationId == 0) {
                    crossOreWar.syncAllCrossStation(serverId);
                } else {
                    crossOreWar.syncCrossStation(crossOreWar.getCrossOreStationInfo(stationId), false);
                }
            }
        }
    }

    public static void sendAllNotice(int activityId, long serverId, int groupId) {
        synchronized (getActivityLock(activityId,groupId)) {
            CrossOreWar crossOreWar = getCrossOreWar(activityId, groupId);
            if (null != crossOreWar) {
                crossOreWar.sendAllNotice(serverId);
            }
        }
    }

    public static void sendAllRecord(int activityId, long serverId, int groupId) {
        synchronized (getActivityLock(activityId,groupId)) {
            CrossOreWar crossOreWar = getCrossOreWar(activityId, groupId);
            if (null != crossOreWar) {
                crossOreWar.sendAllRecord(serverId);
            }
        }
    }

    //获取自己的占领奖励
    public static OreWarProto.CrossOreGetRewardRespMsg.Builder getSelfOccupyReward(int activityId, long userId,int groupId) {
        OreWarProto.CrossOreGetRewardRespMsg.Builder resMsg = OreWarProto.CrossOreGetRewardRespMsg.newBuilder();
        resMsg.setRet(GameErrorCode.E_ORE_WAR_ACTIVITY_NO_FOUND);
        synchronized (getActivityLock(activityId,groupId)) {
            CrossOreWar crossOreWar = getCrossOreWar(activityId,groupId);
            if (null != crossOreWar) {
                return crossOreWar.getSelfPitOccupyReward(userId);
            }
        }
        return resMsg;
    }

    //撤回坑位
    public static OreWarProto.CrossOrePitRecallRespMsg.Builder orePitRecall(int activityId, long userId, UserBaseInfo userBaseInfo, int pitId, int groupId) {
        OreWarProto.CrossOrePitRecallRespMsg.Builder msg = OreWarProto.CrossOrePitRecallRespMsg.newBuilder();
        synchronized (getActivityLock(activityId, groupId)) {
            CrossOreWar crossOreWar = getCrossOreWar(activityId, groupId);
            if (null != crossOreWar) {
                msg = crossOreWar.orePitRecall(userId, userBaseInfo, pitId);
            }
        }
        return msg;
    }

    /**
     * 抢夺矿坑
     */
    public static OreWarProto.CrossOrePitRobRespMsg.Builder robPit(long userId, UserBaseInfo userBaseInfo, int activityId, int pitId, long pitOwnerUserId,
                                                                   String patronsInfoStr, int beautySkillAddition, int patronsSkillAddition, int refugeCount, int groupId) {
        OreWarProto.CrossOrePitRobRespMsg.Builder msg = OreWarProto.CrossOrePitRobRespMsg.newBuilder();
        msg.setRet(GameErrorCode.E_ACTIVITY_NO_FOUND);
        synchronized (getActivityLock(activityId, groupId)) {
            CrossOreWar crossOreWar = getCrossOreWar(activityId, groupId);
            if (crossOreWar != null) {
                msg = crossOreWar.robPit(userId, userBaseInfo, pitId, pitOwnerUserId, patronsInfoStr, beautySkillAddition, patronsSkillAddition, refugeCount);
            }
        }
        return msg;
    }


    public static void allPatronsAbilityChange(long userId, UserBaseInfo userBaseInfo, int activityId, int pitId,
                                               List<UserPatrons> userPatronsList, int beautySkillAddition, int patronsSkillAddition, int groupId) {
        synchronized (getActivityLock(activityId, groupId)) {
            CrossOreWar crossOreWar = getCrossOreWar(activityId, groupId);
            if (null != crossOreWar) {
                crossOreWar.patronsAbilityChange(userId, userBaseInfo, pitId, userPatronsList, beautySkillAddition, patronsSkillAddition);
            }
        }
    }

    public static void allPatronsAbilityChange(long userId, UserBaseInfo userBaseInfo, int activityId, List<OreWarProto.CrossOreWarPatronsSyncMsg> patronsMsgList, int groupId) {
        CrossOreWar crossOreWar = getCrossOreWar(activityId, groupId);
        if (null != crossOreWar) {
            crossOreWar.patronsAbilityChange(userId, userBaseInfo, patronsMsgList);
        }
    }


    //用户的基础信息改变可能会涉及到的更新建筑信息，顺带刷新发送奖励
    public static void baseUserInfoChangeRefresh(Map<Long, UserBaseInfo> infoMap) {
        if (infoMap.size() > 0) {
            for (Map<Integer, CrossOreWar> groupMap : crossOreWarMap.values()) {
                for (CrossOreWar crossOreWar : groupMap.values()) {
                    crossOreWar.updateBaseUserInfo(infoMap);
                }
            }
            UserBaseInfo userBaseInfo = new ArrayList<>(infoMap.values()).get(0);
            if (userBaseInfo.getServerId() > 0) {
                for (Map<Integer, CrossOreWar> groupMap : crossOreWarMap.values()) {
                    for (CrossOreWar crossOreWar : groupMap.values()) {
                        for (long serverId : crossOreWar.getActivityInfo().getServerIdList()) {
                            if (serverId == userBaseInfo.getServerId()) {
                                crossOreWar.refreshCrossOreStation();
                                break;
                            }
                        }
                    }
                }
            }
        }
    }


    public static void unionInfoSync(int type, long serverId, long userId, String unionUid, int groupId) {
        if (type == 0) {//普通的更新内容

        } else if (type == 1) {//商会解散
            sendUnionDismissNamingChangeReward(unionUid);
        } else if (type == 2) {//商会成员加入或者商会成员退出被踢等
            sendUnionNamingJoinQuitReward(unionUid, userId);
        }
    }

    public static void sendUnionDismissNamingChangeReward(String unionUid) {
        for (Map<Integer, CrossOreWar> groupMap : crossOreWarMap.values()) {
            for (CrossOreWar crossOreWar : groupMap.values()) {
                crossOreWar.sendUnionDismissNamingChangeReward(unionUid);
            }
        }
    }

    public static void sendUnionNamingJoinQuitReward(String unionUid, long userId) {
        for (Map<Integer, CrossOreWar> groupMap : crossOreWarMap.values()) {
            for (CrossOreWar crossOreWar : groupMap.values()) {
                crossOreWar.sendUnionNamingJoinQuitReward(unionUid, userId);
            }
        }
    }

    public static void refreshOreStation() {
        for (Map<Integer, CrossOreWar> groupMap : crossOreWarMap.values()) {
            for (CrossOreWar crossOreWar : groupMap.values()) {
                crossOreWar.refreshCrossOreStation();
            }
        }
    }

    //获取用户单个
    public static CrossUserOrePit getCrossUserOrePit(int activityId, int pitId, int groupId) {
        synchronized (getActivityLock(activityId, groupId)) {
            CrossOreWar crossOreWar = getCrossOreWar(activityId, groupId);
            if (null != crossOreWar) {
                return crossOreWar.getCrossUserOrePit(pitId);
            }
        }
        return null;
    }

    //侦查玩家的坑位数据
    public static List<CrossUserOrePit> getCrossUserOrePitList(int activityId, long userId, int groupId) {
        List<CrossUserOrePit> pitList = new ArrayList<>();
//        synchronized (getActivityLock(activityId, groupId)) {
            CrossOreWar crossOreWar = getCrossOreWar(activityId, groupId);
            if (crossOreWar != null) {
                pitList = crossOreWar.getCrossUserOrePitList(userId);
            }
//        }
        return pitList;
    }

    public static List<CrossUserOrePit> getCrossUserOrePitListByAliasId(int activityId, long aliasId, int groupId) {
        List<CrossUserOrePit> pitList = new ArrayList<>();
        synchronized (getActivityLock(activityId, groupId)) {
            CrossOreWar crossOreWar = getCrossOreWar(activityId, groupId);
            if (crossOreWar != null) {
                pitList = crossOreWar.getCrossUserOrePitListByAliasId(aliasId);
            }
        }
        return pitList;
    }

    public static List<CrossUserOrePit> getCrossUserOrePitList(int activityId, int startPitId, int endPitId, int groupId) {
        List<CrossUserOrePit> pitList = new ArrayList<>();
        synchronized (getActivityLock(activityId, groupId)) {
            CrossOreWar crossOreWar = getCrossOreWar(activityId, groupId);
            if (crossOreWar != null) {
                pitList = crossOreWar.getCrossUserOrePitList(startPitId, endPitId);
            }
        }
        return pitList;
    }

    //第一个建筑玩家的前三个坑位信息
    public static List<CrossUserOrePit> getCrossTopBuildingOrePitList(int activityId, int groupId) {
        synchronized (getActivityLock(activityId, groupId)) {
            CrossOreWar crossOreWar = getCrossOreWar(activityId, groupId);
            if (null != crossOreWar) {
                return crossOreWar.getCrossTopBuildingOrePitList();
            }
        }
        return new ArrayList<>();
    }

    /******************************↑用到*********************************************************************************/
    public static boolean isActivityActive(int activityId, int groupId) {
        synchronized (getActivityLock(activityId, groupId)) {
            CrossOreWar crossOreWar = getCrossOreWar(activityId, groupId);
            if (null != crossOreWar) {
                return crossOreWar.isActivityActive();
            }
        }
        return false;
    }

    /****************************************************************************************************************************************************/
    /**
     * 根据活动ID加载活动
     *
     * @param activityId 活动ID
     */
    public static void loadActivity(int activityId) {
        long serverId = CrossBaseServer.getInstance().getServerId();
        synchronized (crossOreWarMap) {
            Map<Integer, UnionActivityGroup> groupMap = Cross2UnionActivityGroupMgr.getGroupMap(activityId);
            if (groupMap == null) {
                logger.error("跨服盐场活动" + activityId + "暂时无分组,加载失败");
                return;
            }
            ActivityInfo acInfo = CrossOreWarActivityMgr.getOpenActivityInfo(activityId);
            if (acInfo != null) {
                if (!crossOreWarMap.containsKey(activityId)) {
                    crossOreWarMap.put(activityId, new ConcurrentHashMap<>());
                    for (UnionActivityGroup group : groupMap.values()) {
                        if (group.getCrossServerId() != serverId) {
                            continue;
                        }
                        int groupId = group.getGroupId();
                        synchronized (getActivityLock(activityId, groupId)) {
                            CrossOreWar crossOreWar = new CrossOreWar(acInfo, groupId);
                            if (crossOreWar.init()) {
                                crossOreWarMap.get(activityId).put(groupId, crossOreWar);
                            } else {
                                logger.error("跨服盐场活动" + activityId + "加载失败");
                            }
                        }
                    }
                }
            }
        }
    }

    /**
     * 清除过期数据
     *
     * @param activityId 活动ID
     */
    private static void removeData(int activityId) {
        crossOreWarMap.remove(activityId);
        activityLock.remove(activityId);
        logger.error("remove crossOreWar activity:{}", activityId);
    }

    public static void removeActivity() {
        Map<Integer, ActivityInfo> activityInfoMap = CrossOreWarActivityMgr.getOpenActivityInfoMap();
        synchronized (crossOreWarMap) {
            for (Map<Integer, CrossOreWar> groupMap : crossOreWarMap.values()) {
                for (CrossOreWar crossOreWar : groupMap.values()) {
                    if (!activityInfoMap.containsKey(crossOreWar.getActivityInfo().getActivityId())) {
                        removeData(crossOreWar.getActivityInfo().getActivityId());
                        break;
                    }
                }
            }
        }
    }

    /**
     * 获取活动锁
     *
     * @param activityId 活动ID
     * @return
     */
    private static synchronized Object getActivityLock(int activityId, int groupId) {
        if (activityLock == null) {
            activityLock = new ConcurrentHashMap<>();
        }
        if (!activityLock.containsKey(activityId)) {
            activityLock.put(activityId, new ConcurrentHashMap<>());
        }
        if (!activityLock.get(activityId).containsKey(groupId)) {
            activityLock.get(activityId).put(groupId, new Object());
        }
        return activityLock.get(activityId).get(groupId);
    }

    private static CrossOreWar getCrossOreWar(int activityId, int groupId) {
        if (groupId == UnionActivityGroupHelper.NO_GROUP_ID){
            return null;
        }
        synchronized (crossOreWarMap) {
            if (!crossOreWarMap.containsKey(activityId)) {
                crossOreWarMap.put(activityId, new ConcurrentHashMap<>());
            }
            Map<Integer, CrossOreWar> integerCrossOreWarMap = crossOreWarMap.get(activityId);
            if (integerCrossOreWarMap.containsKey(groupId)) {
                return integerCrossOreWarMap.get(groupId);
            } else {
                CrossOreWarActivityMgr.reloadActivityInfo(activityId);
                ActivityInfo acInfo = CrossOreWarActivityMgr.getOpenActivityInfo(activityId);
                if (acInfo != null) {
                    UnionActivityGroup groupData = Cross2UnionActivityGroupMgr.getGroupData(activityId, groupId);
                    if (groupData == null) {
                        logger.error("跨服盐场活动" + activityId + "暂时无分组{},加载失败", groupId);
                        return null;
                    }
                    if (groupData.getCrossServerId() != CrossBaseServer.getInstance().getServerId()) {
                        logger.error("跨服盐场活动" + activityId + "分组{}不在本服,加载失败", groupId);
                        return null;
                    }
                    CrossOreWar crossOreWar = new CrossOreWar(acInfo, groupId);
                    if (crossOreWar.init()) {
                        integerCrossOreWarMap.put(groupId, crossOreWar);
                    } else {
                        logger.error("跨服盐场活动" + activityId + "加载失败");
                    }
                    return integerCrossOreWarMap.get(groupId);
                }
            }
            return null;
        }
    }

    @Deprecated
    //把所有请求任务添加进去
    public static void addTask(int activityId, GeneralTask task, int groupId) {
        synchronized (getActivityLock(activityId, groupId)) {
            CrossOreWar crossOreWar = getCrossOreWar(activityId, groupId);
            if (crossOreWar != null) {
                crossOreWar.addTask(task);
            }
        }
    }

    public static void timerTask() {
        for (Map<Integer, CrossOreWar> groupMap : crossOreWarMap.values()) {
            for (CrossOreWar crossOreWar : groupMap.values()) {
                synchronized (getActivityLock(crossOreWar.getActivityInfo().getActivityId(), crossOreWar.getGroupId())) {
                    crossOreWar.timerTask();
                }
            }
        }
    }

    @Override
    public boolean stop() {
        return false;
    }

    @Override
    public boolean init() throws Exception {
        return reload();
    }

    @Override
    public boolean reloadConfig() throws Exception {
        return true;
    }

    @Override
    public boolean save() {
        for (Map<Integer, CrossOreWar> groupMap : crossOreWarMap.values()) {
            for (CrossOreWar crossOreWar : groupMap.values()) {
                crossOreWar.save();
            }
        }
        return true;
    }

    @Override
    public boolean reloadData() {
        return true;
    }


    public boolean removeExpireData() {
        List<Integer> acList = new ArrayList<>();
        long nowTime = System.currentTimeMillis();
        for (Integer activityId : crossOreWarMap.keySet()) {
            Map<Integer, CrossOreWar> groupOreMap = crossOreWarMap.get(activityId);
            for (Integer groupId : groupOreMap.keySet()) {
                CrossOreWar crossOreWar = groupOreMap.get(groupId);
                if (crossOreWar.getActivityInfo() == null || (nowTime > crossOreWar.getActivityInfo().getEndShowTime() * 1000 + 1 * 3600 * 1000)) {
                    acList.add(activityId);
                }
            }
        }
        for (Integer activityId : acList) {
            crossOreWarMap.remove(activityId);
        }
        return true;
    }
}
